import {
	DataViewCtrlActionType,
	IDataViewCtrlStore,
	IDataViewCtrlAbility,
	IDataViewCtrlController,
	IDataViewCtrlControllerParams,
	IParam,
	IHttpResponse,
	ICtrlActionResult,
	IDataViewCtrlModel,
	IUIService,
	ICodeListItem,
    IEntityDetail,
} from '@/core/interface';
import { ControlVOBase } from '@/core/modules';
import DataViewService from '@/core/modules/ctrl-service/data-view-service';
import { AuthUtil, deepCopy } from '@/core/utils';
import { MDCtrlController } from './md-ctrl-controller';

/**
 * 卡片视图部件控制器
 *
 * @export
 * @class DataViewCtrlController
 * @extends {(MDCtrlController<T | DataViewCtrlActionType, IDataViewCtrlStore, IDataViewCtrlAbility>)}
 * @implements {IDataViewCtrlController}
 * @template T
 */
export class DataViewCtrlController
	extends MDCtrlController<
		DataViewCtrlActionType,
		IDataViewCtrlStore,
		IDataViewCtrlAbility
	>
	implements IDataViewCtrlController<IDataViewCtrlStore, IDataViewCtrlAbility>
{
	/**
	 * 加载模式
	 *
	 * @protected
	 * @type {('loadDefault' | 'loadMore')}
	 * @memberof DataViewCtrlController
	 */
	protected isLoadMore = false;

	/**
	 * data数据copy
	 *
	 * @protected
	 * @type IParam[]
	 * @memberof DataViewCtrlController
	 */
	protected copyData: IParam[] = [];

	/**
	 * 行激活模式 (0: 无激活、1: 单击激活、2: 双击激活)
	 *
	 * @protected
	 * @type {(0 | 1 | 2)}
	 * @memberof DataViewCtrlController
	 */
	protected rowActiveMode!: 0 | 1 | 2;

	/**
	 * 卡片视图部件服务
	 *
	 * @type {GridService<ControlVOBase>}
	 * @memberof GridController
	 */
	declare ctrlService: DataViewService<ControlVOBase>;

	/**
	 * 卡片视图部件模型
	 *
	 * @protected
	 * @type {IDataViewCtrlModel}
	 * @memberof DataViewCtrlController
	 */
	protected declare readonly model: IDataViewCtrlModel;

	/**
	 * Creates an instance of DataViewCtrlController.
	 * @param {IDataViewCtrlControllerParams<DataViewCtrlActionType, IDataViewCtrlAbility>} params
	 * @memberof DataViewCtrlController
	 */
	public constructor(
		params: IDataViewCtrlControllerParams<
			DataViewCtrlActionType,
			IDataViewCtrlAbility
		>
	) {
		super(params);
		this.rowActiveMode = params.rowActiveMode;
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {IDataViewCtrlControllerParams<DataViewCtrlActionType, IDataViewCtrlAbility>} params
	 * @memberof DataViewCtrlController
	 */
	protected processCtrlInit(
		params: IDataViewCtrlControllerParams<
			DataViewCtrlActionType,
			IDataViewCtrlAbility
		>
	) {
		super.processCtrlInit(params);
		this.name = 'dataview';
		Object.assign(this.store, { loadMoreStatus: false });
	}

	/**
	 * 卡片视图部件项单击
	 *
	 * @param {IParam} item
	 * @param {MouseEvent} event
	 * @memberof DataViewCtrlController
	 */
	public handleItemClick(item: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(item);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === item.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(item);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 1) {
			this.emit('dataActive', [item]);
		}
	}

	/**
	 * 卡片视图部件项双击
	 *
	 * @param {IParam} item
	 * @param {MouseEvent} event
	 * @memberof DataViewCtrlController
	 */
	public handleItemDbClick(item: IParam, event: MouseEvent) {
		const selections = this.store.selections;
		if (this.singleSelect) {
			selections.length = 0;
			selections.push(item);
		} else {
			const index = selections.findIndex(
				(select: IParam) => select.srfkey === item.srfkey
			);
			//	未选中
			if (index === -1) {
				this.store.selections.push(item);
			} else {
				this.store.selections.splice(index, 1);
			}
		}
		this.emit('selectionChange', this.getData());
		if (this.rowActiveMode === 2) {
			this.emit('dataActive', [item]);
		}
	}

	/**
	 * 选中数据
	 *
	 * @param {IParam[]} selections
	 * @memberof DataViewCtrlController
	 */
	public handleSelectionChange(selections: IParam[]) {
		this.store.selections = selections;
		this.emit('selectionChange', this.getData());
	}

	/**
	 * 加载更多
	 *
	 * @return {*}
	 * @memberof DataViewCtrlController
	 */
	async loadMore() {
		if (this.store.data.length >= this.store.totalRecord) {
			return;
		}
		this.isLoadMore = true;
		this.store.curPage++;
		await this.load();
		this.isLoadMore = false;
	}

	/**
	 * 异步行为之后
	 *
	 * @param {string} action
	 * @param {IHttpResponse} response
	 * @memberof DataViewCtrlController
	 */
	public afterAsyncAction(action: string, response: IHttpResponse,otherOpt: any = {}) {
        this.store.loadMoreStatus = this.store.data.length < this.store.totalRecord;
		return super.afterAsyncAction(action, response, otherOpt);
	}

	/**
	 * 删除
	 *
	 * @param {string} action
	 * @param {IHttpResponse} response
	 * @memberof DataViewCtrlController
	 */
	async remove(datas: IParam[] = []): Promise<ICtrlActionResult> {
		const { removeAction } = this.actions;
		if (!removeAction) {
			App.getNotificationHelper().warning(App.ts("widget.common.warn","警告"), App.ts("widget.dataview.nodeleteaction","未配置删除行为"));
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const deleteItems: IParam[] = [];
		//	已选中数据
		datas.forEach((record: IParam) => {
			if (record.srfuf === '0') {
				const index = this.store.data.findIndex(
					(i: IParam) => i.srfkey === record.srfkey
				);
				if (index !== -1) {
					this.store.data.splice(index, 1);
				}
			} else {
				deleteItems.push(record);
			}
		});
		if (deleteItems.length === 0) {
			return { ok: true, data: this.getData(), rowData: { status: 200 } };
		}
		let dataInfo = '';
		deleteItems.forEach((item: IParam, index: number) => {
			if (index < 5) {
				if (dataInfo !== '') {
					dataInfo += '、';
				}
				dataInfo += item.srfmajortext ? item.srfmajortext : '';
			}
		});
		if (!dataInfo) {
			dataInfo = `${App.ts("widget.dataview.check","选中")}${deleteItems.length}${App.ts("widget.dataview.piece","条数据")}`;
		} else {
			if (deleteItems.length < 5) {
				dataInfo += ` ${App.ts("widget.dataview.total","共")}${deleteItems.length}${App.ts("widget.dataview.piece","条数据")}`;
			} else {
				dataInfo += `...${deleteItems.length}${App.ts("widget.dataview.piece","条数据")}`;
			}
		}
		//	去除null和undefined
		dataInfo = dataInfo.replace(/[null]/g, '').replace(/[undefined]/g, '');
		const removeData = () => {
            const { entityCodeName } = this.model;
            const entityDetails = App.getAppEntityConfig();
            const entity = entityDetails.find((detail: IEntityDetail) => detail.codeName == entityCodeName)
            if (!entity) {
                return 
            }
            const keys: string[] = [];
			deleteItems.forEach((item: IParam) => keys.push(item[entity.keyField.toLowerCase()]));
			if (keys.length === 0) {
				return;
			}
			const { context, viewParams } = this.store;
			let _removeAction = removeAction;
			if (Object.is(removeAction, 'RemoveTemp') && keys.length > 1) {
				_removeAction = 'RemoveBatchTemp';
			}
			const tempContext: any = deepCopy(context);
			const _keys: string[] | string = keys.length > 1 ? keys : keys[0];
			const arg = { [entityCodeName.toLowerCase()]: _keys };
			let promises: Promise<any> | null = null;
			if (keys && keys.length > 1) {
				const promiseArr: any = [];
				(_keys as string[]).forEach((ele: any) => {
					Object.assign(tempContext, { [entityCodeName.toLowerCase()]: ele });
					Object.assign(arg, { viewParams: deepCopy(viewParams) });
					Object.assign(arg, { [entityCodeName.toLowerCase()]: ele });
					promiseArr.push(
						this.ctrlService.delete(_removeAction, tempContext, arg)
					);
				});
				promises = Promise.all(promiseArr);
			} else {
				Object.assign(tempContext, { [entityCodeName.toLowerCase()]: _keys });
				Object.assign(arg, { viewParams: deepCopy(viewParams) });
				promises = this.ctrlService.delete(_removeAction, tempContext, arg);
			}
			this.beforeAsyncAction('remove', tempContext, arg);
			if (promises) {
				promises
					.then(async (response: any) => {
						this.afterAsyncAction('remove', response, { afterNotification: `, ${response.info}`});
						//删除items中已删除的项
						this.store.totalRecord -= deleteItems.length;
						this.emit('remove', deleteItems);
						this.store.selections = [];
						this.refresh();
					})
					.catch(async (error: any) => {
						this.afterAsyncAction('remove', error);
					});
			}
		};
		App.getDialogHelper().confirm(
			App.ts("widget.common.warn","警告"),
			`${App.ts("widget.common.confirmtodelete","确认要删除")}${dataInfo},${App.ts("widget.common.delnotberecoverable","删除操作将不可恢复")}?`,
			() => {
				removeData();
			}
		);
		return { ok: true, data: this.getData(), rowData: { status: 200 } };
	}

	/**
	 * 刷新
	 *
	 * @param {(IParam | undefined)} [args]
	 * @return {*}  {Promise<boolean>}
	 * @memberof DataViewCtrlController
	 */
	public async refresh(args?: IParam | undefined): Promise<boolean> {
		try {
			const result = await this.load();
			if (result.ok) {
				return true;
			}
		} catch (error) {
			return false;
		}
		return false;
	}

	/**
	 * 处理加载数据变化
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof DataViewCtrlController
	 */
	protected handleLoadDataChange(data: IParam[]): void {
		if (!this.isLoadMore) {
			this.store.data = data;
			this.copyData = [];
			this.handleGroup();
		} else {
			this.store.data = [...this.store.data, ...data];
			this.handleGroup(data);
		}
		this.handleDefaultSelect();
		this.handleItemUIActionGroup();
		setTimeout(() => {
			this.copyData = [...this.store.data];
		}, 0);
	}

	/**
	 * 处理分组
	 *
	 * @protected
	 * @return {*}
	 * @memberof MDCtrlController
	 */
	protected handleGroup(data: IParam[] = []) {
		const { enableGroup, groupMode } = this.model;
		if (!enableGroup) {
			return;
		}
		if (groupMode === 'AUTO') {
			if (this.copyData && this.copyData.length > 0) {
				this.handleAutoLoadMoreData(data);
			} else {
				this.handleAutoGroup();
			}
		} else if (groupMode === 'CODELIST') {
			if (this.copyData && this.copyData.length > 0) {
				this.handleCodeListLoadMoreData(data);
			} else {
				this.handleCodeListGroup();
			}
		}
	}

	/**
	 * @description 处理自动分组时点击 加载更多 获取的数据
	 * @protected
	 * @param {IParam[]} data
	 * @memberof DataViewCtrlController
	 */
	protected async handleAutoLoadMoreData(_data: IParam[]) {
		if (_data.length === 0) {
			return;
		}
		const { data } = this.store;
		if (data.length === 0) {
			return;
		}
		//  分组属性标识
		const field = this.model.groupField as string;
		//  分组属性代码表
		const fieldCodeList = this.model.groupFieldCodeListTag;
		//  分组列标识
		const dataIndex = this.model.groupDataIndex as string;
		const resultMap: Map<string, IParam[]> = new Map();
		const codeItems: IParam[] = [];
		if (fieldCodeList) {
			const result = await App.getAppCodeListHelper().getCodeListItems(
				fieldCodeList
			);
			if (result.ok) {
				codeItems.push(...result.data);
			}
		}
		_data.forEach((item: IParam) => {
			const items = resultMap.get(item[field]) || [];
			items.push(item);
			resultMap.set(item[field], items);
		});
		resultMap.forEach((value: IParam[], key: string) => {
			const item =
				codeItems.length > 0
					? codeItems.find((item: IParam) => item.value === key)
					: { text: key };
			const index = this.copyData.findIndex((item: IParam) =>
				Object.is(item.key, `group-item__${key}`)
			);
			if (index < 0) {
				this.copyData.push({
					key: `group-item__${key}`,
					srfkey: `group-item__${key}`,
					srfmajortext: item
						? item.text
						: App.ts('widget.dataview.other', '其他'),
					[dataIndex]: item
						? item.text
						: App.ts('widget.dataview.other', '其他'),
					isGroupItem: true,
					children: value,
				});
			} else {
				if (!this.copyData[index].children) {
					this.copyData[index].children = [];
				}
				this.copyData[index].children.push(...value);
			}
		});
		this.store.data = this.copyData;
	}

	/**
	 * @description 处理代码表分组时点击 加载更多 获取的数据
	 * @protected
	 * @param {IParam[]} data
	 * @memberof DataViewCtrlController
	 */
	protected async handleCodeListLoadMoreData(_data: IParam[]) {
		//  分组代码表标识
		const codeListTag = this.model.groupCodeListTag as string;
		//  分组属性标识
		const field = this.model.groupField as string;
		//  分组列标识
		const dataIndex = this.model.groupDataIndex as string;
		if (!codeListTag) {
			return;
		}
		const { context, viewParams } = this.store;
		const result = await App.getAppCodeListHelper().getCodeListItems(
			codeListTag,
			context,
			viewParams
		);
		if (!result.ok || result.data.length === 0) {
			return;
		}
		const keys: (string | number)[] = result.data.map(
			(d: ICodeListItem) => d.value
		);
		this.copyData.forEach((item: IParam) => {
			const _items = _data.filter((_item: IParam) => {
				return _item[field] === item.value;
			});
			if (!item.children) {
				item.children = [];
			}
			if (_items.length > 0) {
				item.children.push(..._items);
			}
		});
		const otherItems = _data.filter(
			(d: IParam) => keys.indexOf(d[field]) === -1
		);
		if (otherItems.length > 0) {
			const index = this.copyData.findIndex((item: IParam) =>
				Object.is(item.key, 'group-other-item')
			);
			if (index < 0) {
				this.copyData.push({
					key: `group-other-item`,
					srfkey: `group-other-item`,
					srfmajortext: App.ts('widget.dataview.other', '其他'),
					[dataIndex]: App.ts('widget.dataview.other', '其他'),
					isGroupItem: true,
					children: otherItems,
				});
			} else {
				this.copyData[index].children.push(...otherItems);
			}
		}
		this.store.data = this.copyData;
	}

	/**
	 * 处理项界面行为组
	 *
	 * @protected
	 * @memberof DataViewCtrlController
	 */
	protected async handleItemUIActionGroup() {
		const { uIActionGroup } = this.model;
		if (uIActionGroup) {
			const uIActionGroupModel = deepCopy(uIActionGroup);
			this.handleChildrenUIAction(this.store.data, uIActionGroupModel);
		}
	}

	/**
	 * 处理子项界面行为
	 *
	 * @param {IParam[]} data
	 * @memberof DataViewCtrlController
	 */
	handleChildrenUIAction(data: IParam[], model: any): void {
		if (data && data instanceof Array) {
			data.forEach((item: IParam) => {
				if (item && !item.isGroupItem) {
					AuthUtil.calcActionItemAuthState(
						item.getDo(),
						model,
						this.uiService as IUIService,
                        this.store.viewCtx.view?.getModel()
					);
					item.uIActionGroup = model;
				} else if (item && item.isGroupItem) {
					this.handleChildrenUIAction(item.children, model);
				}
			});
		}
	}

	/**
	 * 获取能力
	 *
	 * @template A
	 * @return {*}  {A}
	 * @memberof GridController
	 */
	getAbility(): IDataViewCtrlAbility {
		return {
			...super.getAbility(),
			remove: this.remove.bind(this),
			loadMore: this.loadMore.bind(this),
		};
	}
}
